package com.crazymaker.springcloud.websocket.netty.handler;

import com.crazymaker.springcloud.base.auth.AuthUtils;
import com.crazymaker.springcloud.base.auth.Payload;
import com.crazymaker.springcloud.common.constants.SessionConstants;
import com.crazymaker.springcloud.websocket.netty.event.SecurityCheckCompleteEvent;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.FullHttpMessage;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;

import static com.crazymaker.springcloud.netty.util.HttpUtil.closeUnauthChannelAfterWrite;

@Slf4j
public class ClientTokenCheckHandler extends ChannelInboundHandlerAdapter {

    public static final AttributeKey SECURITY_CHECK_COMPLETE_ATTRIBUTE_KEY =
            AttributeKey.valueOf("SECURITY_CHECK_COMPLETE_ATTRIBUTE_KEY");

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof FullHttpMessage) {
            //extracts token information  from headers
            HttpHeaders headers = ((FullHttpMessage) msg).headers();
            String token = Objects.requireNonNull(headers.get(SessionConstants.AUTHORIZATION_HEAD));


            //extracts appID information  from headers
            String appID = Objects.requireNonNull(headers.get(SessionConstants.APP_ID));

            if (null == token || null == appID) {
                // 参数校验、设置响应
                String content = "请带上正确令牌，再发起websocket连接！！！";
                closeUnauthChannelAfterWrite(ctx, content);
                return;

            }
            Payload<String> payload = null;
            // 在此处获取URL、Headers等信息并做校验，通过throw异常来中断链接。
            try {
//                payload = AuthUtils.decodeRsaToken(token);
                payload = AuthUtils.verifyJwtRsaToken(token);
            } catch (Exception e) {
                // 解码异常、设置响应
                String content = "请带上正确令牌，再发起websocket连接！！！";
                closeUnauthChannelAfterWrite(ctx, content);
                return;
            }
            if (null == payload) {
                // 解码异常、设置响应
                String content = "请带上正确令牌，再发起websocket连接！！！";
                closeUnauthChannelAfterWrite(ctx, content);
                return;

            }
            String account = payload.getId();
            SecurityCheckCompleteEvent complete = new SecurityCheckCompleteEvent(token, appID,account);
            ctx.channel().attr(SECURITY_CHECK_COMPLETE_ATTRIBUTE_KEY).set(complete);
            ctx.fireUserEventTriggered(complete);
        }
        //other protocols
        super.channelRead(ctx, msg);
    }

}